#ifndef AI_REFLEX_H
#define AI_REFLEX_H



#include "ai.h"
#include <utility>



//! @brief The main algorithm class
class reflex_algorithm: public algorithm
{

public:

	//! @brief Constructor only assignes the name
	reflex_algorithm()
	{
		name = "Reflex algorithm";
	};

	/** @brief	Cloning function for init purposes
	*	@return	clone of the algorithm
	*/
	virtual algorithm* clone()
	{
		reflex_algorithm* cl = clonetpl< reflex_algorithm >();
		return cl;
	};

	//! @brief Function called at the beginning of every turn
	virtual void get_commands();


private:

	//! @brief Checks if there are any units in danger and adds appropriate commands to move_commands gueue
	void check_dangerous_places();
	//! @brief Checks if there are any units to attack to and adds appropriate commands to fire_commands gueue
	void check_attackable_places();
	/**	@brief	Finds safe place for given unit
	*	@param	u unit, for which to find the safe place, constraint: u != 0
	*	@param	state game_state, where to find the safe place, constraint: state != 0
	*	@return	coordinates of the safe place
	*/
	std::pair< int, int > find_safe_place( unit* u, game_state* state );
	/** @brief Finds, if there is some attackable unit, if not, moves closer to any of the opponents units
	*	@param state game_state where to compute commands, , constraint: state != 0
	*/
	void find_target_or_move( game_state* state );
	/**	@brief	Finds the best attacking and attackable unit
	*	@param	state state where to find the pair, constraint: state != 0
	*	@return	unit number to attack with and coordinates where to attack
	*/
	std::pair< int, std::pair< int, int > > find_best_target( game_state* state );
	/**	@brief	Finds the best target for given unit
	*	@param	u unit, for which to find the target, constraint: u != 0
	*	@param	state game_state, where to find the target, constraint: state != 0
	*	@return	coordinates of the best target
	*/
	std::pair< int, int > find_best_target_unit( unit* u, game_state* state );
	/**	@brief	Checks if any unit can attack somebody
	*	@param	state game_state, where to find the targets, constraint: state != 0
	*	@return	True if there is at least one such an unit, false if not
	*/
	bool can_anybody_attack( game_state* state );
	/**	@brief Finds pair unit and place where to move
	*	gets unit, that is the closest to the oponnent and finds a place for it, that is even closer
	*	@param	state game_state where to find the pair, constraint: state != 0
	*	@return	unit number to move with and coordinates where to move
	*/
	std::pair< int, std::pair< int, int > > find_better_place( game_state* state );
	/**	@brief Finds better place for given unit
	*	finds the closest opponent and finds a place for it, that is even closer
	*	@param	u unit, for which to find the place, constraint: u != 0
	*	@param	state game_state, where to find the place, constraint: state != 0
	*	@return	coordinates of the better place and distance there
	*/
	std::pair < double, std::pair< int, int > > find_better_place_unit( unit* u, game_state* state );

	//! list of commands for moving
	std::list< std::string > move_commands;
	//! list of commands for attacking
	std::list< std::string > fire_commands;

	//! remaining time (for computing purposes)
	int time;
	//! given state
	game_state* state;

};



#endif